<template>
  <div style="display: flex">
    <div class="tree-box">
      <el-tree
        :data="data"
        check-strictly
        show-checkbox
        node-key="id"
        @check-change="changeLeftCheckStatus"
        @check="handleCheck"
      >
        <span class="custom-tree-node" slot-scope="{ node, data }">
          <span>{{ node.label }}</span>
          <span>
            <el-checkbox
              :value="data.rightCheckStatus"
              :disabled="data.rightDisabled"
              @click.stop.native="() => {}"
              @change="(val) => changeRightCheckStatus(val, data)"
            ></el-checkbox>
          </span>
        </span>
      </el-tree>
    </div>
    <div class="tree-box">
      <el-tree :data="rightActiveData">
        <span class="custom-tree-node" slot-scope="{ node, data }">
          <span>{{ node.label }}</span>
          <span>
            <el-button
              type="text"
              size="mini"
              @click="() => removeActive(node, data)"
            >
              Delete
            </el-button>
          </span>
        </span>
      </el-tree>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      data: [],
      defaultProps: {
        children: "children",
        label: "label",
      },
      rightActiveData: [],
      resultData: [],
    };
  },
  watch: {
    resultData(newVal) {
      console.log(newVal, "newVal");
      this.rightActiveData = [];
      this.getRightData(newVal);
    },
  },
  mounted() {
    const resData = [
      {
        label: "一级 1",
        id: "1",
        children: [
          {
            label: "二级 1-1",
            id: "1-1",
            children: [
              {
                label: "三级 1-1-1",
                id: "1-1-1",
                children: [
                  {
                    id: "1-1-1-1",
                    label: "四级 1-1-1-1",
                  },
                ],
              },
            ],
          },
        ],
      },
      {
        label: "一级 2",
        id: "2",
        children: [
          {
            label: "二级 2-1",
            id: "2-1",
            children: [
              {
                id: "2-1-1",
                label: "三级 2-1-1",
              },
            ],
          },
          {
            label: "二级 2-2",
            id: "2-2",
            children: [
              {
                id: "2-2-1",
                label: "三级 2-2-1",
              },
            ],
          },
        ],
      },
      {
        label: "一级 3",
        id: "3",
        children: [
          {
            label: "二级 3-1",
            id: "3-1",
            children: [
              {
                id: "3-1-1",
                label: "三级 3-1-1",
              },
            ],
          },
          {
            label: "二级 3-2",
            id: "3-2",
            children: [
              {
                id: "3-2-1",
                label: "三级 3-2-1",
              },
            ],
          },
        ],
      },
    ];
    this.data = this.patchStatusField(resData);
  },
  methods: {
    getRightData(params) {
      const paramsIdList = params.map((item) => item.id);
      const nodeDataList = [];
      const setNodeDataList = (paramsIdList, data) => {
        data.forEach((item) => {
          if (paramsIdList.includes(item.id)) {
            nodeDataList.push(item);
          }
          if (item.children && item.children.length) {
            setNodeDataList(paramsIdList, item.children);
          }
        });
      };
      setNodeDataList(paramsIdList, this.data);
      console.log(nodeDataList, "nodeDataList");

      const setRightActiveData = () => {
        nodeDataList.forEach((item) => {
          if (item.checkedPosition == "left") {
            const newItem = { ...item };
            newItem.children = [];
            this.rightActiveData.push(newItem);
          } else {
            const copyData = JSON.parse(JSON.stringify(nodeDataList));
            const pNode = this.queryParentNodeById(copyData, item.id);
            console.log(pNode, "pNode");
            if (!pNode || (pNode && pNode.checkedPosition === "left")) {
              this.rightActiveData.push(pNode);
            }
          }
        });
      };
      setRightActiveData();
    },
    //获取父级元素
    queryParentNodeById(node, id) {
      let parentNode;
      for (let i = 0; i < node.length; i++) {
        const item = node[i];
        if (item.children?.some((node) => node.id === id)) {
          parentNode = item;
          break;
        } else if (item.children?.length) {
          const res = this.queryParentNodeById(item.children, id);
          if (res) {
            parentNode = res;
            break;
          }
        }
      }
      return parentNode;
    },
    //修改右侧选中状态
    changeRightCheckStatus(val, data) {
      this.editChildrenRightCheckStatus(val, [data]);
    },
    //修改子级节点rightCheckStatus
    editChildrenRightCheckStatus(val, data) {
      for (const item of data) {
        item.rightCheckStatus = val;
        item.disabled = val;
        item.checkedPosition = "right";
        this.setParam(item.id, item.checkedPosition, val);
        if (item.children && item.children.length) {
          this.editChildrenRightCheckStatus(val, item.children);
        }
      }
    },
    //初始化字段状态
    patchStatusField(data) {
      for (const item of data) {
        this.$set(item, "rightCheckStatus", false);
        this.$set(item, "disabled", false);
        this.$set(item, "checkedPosition", "");
        this.$set(item, "rightDisabled", false);
        if (item.children && item.children.length) {
          this.patchStatusField(item.children);
        }
      }
      return data;
    },
    //修改左侧选中状态
    changeLeftCheckStatus(data, checked) {
      data.rightDisabled = checked;
      data.checkedPosition = "left";
      this.setParam(data.id, data.checkedPosition, checked);
    },
    setParam(id, checkedPosition, checked) {
      const param = {
        id,
        checkedPosition,
      };
      if (checked) {
        const data = this.resultData.find((item) => item.id === param.id);
        if (!data) {
          this.resultData.push(param);
        }
      } else {
        const paramIndex = this.resultData.findIndex((item) => item.id === id);
        if (paramIndex > -1) {
          this.resultData.splice(paramIndex, 1);
        }
      }
    },
    //
    handleCheck(heckedNodes, checkedKeys) {
      console.log("heckedNodes:", heckedNodes);
      console.log("checkedKeys:", checkedKeys);
    },
    //右侧删除事件
    removeActive(node, data) {
      console.log(node);
      console.log(data);
    },
  },
};
</script>
<style scoped>
.tree-box {
  width: 300px;
  height: 500px;
  border: 1px solid #ccc;
  overflow-y: auto;
  & + .tree-box {
    margin-left: 20px;
  }
}
</style>
